package yunjiao.designpatterns.combinator;

import java.util.function.Function;

/**
 * 解析器接口
 *
 * @author yangyunjiao
 */
@FunctionalInterface
public interface Parser<T> {
    ParseResult<T> parse(String input);

    // 组合子方法
    default <U> Parser<U> map(Function<T, U> mapper) {
        return input -> {
            ParseResult<T> result = this.parse(input);
            if (result.success) {
                return ParseResult.success(mapper.apply(result.value), result.remaining);
            }
            return ParseResult.failure(result.error);
        };
    }

    default <U> Parser<U> flatMap(Function<T, Parser<U>> binder) {
        return input -> {
            ParseResult<T> result = this.parse(input);
            if (result.success) {
                return binder.apply(result.value).parse(result.remaining);
            }
            return ParseResult.failure(result.error);
        };
    }

    default Parser<T> or(Parser<T> other) {
        return input -> {
            ParseResult<T> result = this.parse(input);
            if (result.success) {
                return result;
            }
            return other.parse(input);
        };
    }
}
